from django.shortcuts import render,redirect
#导包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#导入类视图
from django.views import View

import json
from django.core.serializers import serialize
from rest_framework.response import Response
from rest_framework.views import APIView
#导入加密库
import hashlib
#导入图片库
#绘画库
from PIL import ImageDraw
#字体库
from PIL import ImageFont
#图片库
from PIL import Image
#随机库
import random
#文件流
import io

import requests

#导入上传文件夹配置
from mydjango.settings import UPLOAD_ROOT
import os

#导入原生sql模块
from django.db import connection

import jwt

#导入redis数据库
import redis

#导入时间模块
import time

import hmac
import base64
from hashlib import sha256
import urllib

#导入公共目录变量
from mydjango.settings import BASE_DIR

#导包
from django.db.models import Q,F

#导入dwebsocket的库
from dwebsocket.decorators import accept_websocket
import uuid

from myapp.models import User,Cate
from myapp.myser import CateSer,UserSer


#定义ip地址和端口
host = "127.0.0.1"
port = 6379

#链接对象
r = redis.Redis(host=host,port=port)


from django.utils.deprecation import MiddlewareMixin

#自定义中间件类
class MyMiddleWare(MiddlewareMixin):

	#请求之前
	def process_request(self,request):
		# uid = request.GET.get("uid")
		# clinet_jwt = request.GET.get("jwt",None)

		# if clinet_jwt == None:
		# 	return HttpResponse('你没有带上令牌')

		# print(uid)
		# decode_jwt = jwt.decode(clinet_jwt,'123',algorithms=['HS256'])
		# if decode_jwt['uid'] != str(uid):
		# 	return HttpResponse('你篡改了用户id')

		pass

	#模板渲染之前
	def process_view(self,request,view_func,view_args,view_kwargs):
		pass

	#请求之后
	def process_response(self,request,response):
		return response

#装饰器
def my_decorator(func):
	def wrapper(request,*args,**kwargs):
		print('这个装饰器被调用了')
		# print('请求接口地址是%s' % request.path)

		# #判断jwt逻辑
		# uid = request.GET.get("uid")
		# clinet_jwt = request.GET.get("jwt",None)


		# decode_jwt = jwt.decode(clinet_jwt,'123',algorithms=['HS256'])
		# if decode_jwt['uid'] != str(uid):
		# 	return HttpResponse('你篡改了用户id')

		return func(request,*args,**kwargs)

	return wrapper

#类装饰器调用
from django.utils.decorators import method_decorator

#用户信息类
class UserInfo(APIView):
	@method_decorator(my_decorator)
	def get(self,request):

		uid = request.GET.get("uid")

		#查询数据
		user = User.objects.get(id=int(uid))

		#序列化对象
		user_ser = UserSer(user)

		return Response(user_ser.data)



#更新用户数据
class UpdateUser(APIView):

	def get(self,request):

		img = request.GET.get("img")
		uid = request.GET.get("uid")

		#查询数据
		user = User.objects.get(id=int(uid))
		user.img = img
		user.save()

		return Response({'code':200,'message':'更新成功'})

#定义七牛云存储接口
from qiniu import Auth

class QiNiu(APIView):

	def get(self,request):

		#定义密钥
		q = Auth('E2IZM3koC1GR1DUqJHactmixzdyZZhx0edBKqDsk','GDnMkvRoE_kFhCSuvdqQj0VcNsRDOHzYJJ_bVd0_')
		#指定上传空间
		token = q.upload_token('upload1906')

		print(token)

		res = {}
		res['token'] = token

		return Response(res)


#定义上传视图类
class UploadFile(View):

	def post(self,request):

		#接收参数
		img = request.FILES.get("file")

		#建立文件流对象
		f = open(os.path.join(UPLOAD_ROOT,'',img.name),'wb')

		#写入服务器端
		for chunk in img.chunks():
			f.write(chunk)
		f.close()

		#返回文件名
		return HttpResponse(json.dumps({'filename':img.name},ensure_ascii=False),content_type='application/json')





#构造钉钉回调方法
def ding_back(request):

    #获取code
    code = request.GET.get("code")

    t = time.time()
    #时间戳
    timestamp = str((int(round(t * 1000))))
    appSecret ='ly-AzMKMmCKQP3geaILT_An32kEfKO3HeOtApy5CgKwjytevVZC0WYsT2gxMB160'
    #构造签名
    signature = base64.b64encode(hmac.new(appSecret.encode('utf-8'),timestamp.encode('utf-8'), digestmod=sha256).digest())
    #请求接口，换取钉钉用户名
    payload = {'tmp_auth_code':code}
    headers = {'Content-Type': 'application/json'}
    res = requests.post('https://oapi.dingtalk.com/sns/getuserinfo_bycode?signature='+urllib.parse.quote(signature.decode("utf-8"))+"&timestamp="+timestamp+"&accessKey=dingoaukgkwqknzjvamdqh",data=json.dumps(payload),headers=headers)

    res_dict = json.loads(res.text)
    print(res_dict)
    return HttpResponse(res.text)


#新浪微博回调
def wb_back(request):

	#获取code
	code = request.GET.get('code')
	#定义微博认证地址
	access_token_url = "https://api.weibo.com/oauth2/access_token"

	#参数
	res = requests.post(
	access_token_url,
	data={

		"client_id":"3440988304",
		"client_secret":"15dde1e8af983da29490e5ac5de10f55",
		"grant_type":"authorization_code",
		"code":code,
		"redirect_uri":"http://127.0.0.1:8000/md_admin/weibo"
	})

	#转换类型
	res = json.loads(res.text)


	#换取新浪微博昵称 json
	result = requests.get('https://api.weibo.com/2/users/show.json',params={'access_token':res['access_token'],'uid':res['uid']})

	result = json.loads(result.text)

	#判断该用户是否曾经登录过
	user = User.objects.filter(username=str(result['name'])).first()

	sina_id = ''
	user_id = ''

	if user:
		sina_id = user.username
		user_id = user.id
	else:
		#手动创建账号
		user = User(username=str(result['name']),password='')
		user.save()

		sina_id = result['name']

		#查询一下刚刚入库的新账号id
		user = User.objects.filter(username=str(result['name'])).first()
		user_id = user.id

	return redirect("http://localhost:8080?sina_id="+sina_id+"&uid="+str(user_id))
	#return HttpResponse(result['name'])


#登录接口
class Login(APIView):

	def get(self,request):

		#接收参数
		username = request.GET.get('username','null')
		password = request.GET.get('password','null')

		#查询数据
		user = User.objects.filter(username=username,password=make_password(password)).first()

		if user:
			res = {}
			res['code'] = 200
			res['message'] = '登录成功'
			res['username'] = user.username
			res['uid'] = user.id
			#加入jwt令牌机制
			encode_jwt = jwt.encode({'uid':str(user.id)},'123',algorithm='HS256')
			encode_str = str(encode_jwt,'utf-8')
			res['jwt'] = encode_str
			return Response(res)
		else:
			res = {}
			res['code'] = 405
			res['message'] = '用户名或者密码错误'
			return Response(res)

			



#递归层级关系
def xTree(datas):
	lists = []
	tree = {}
	parent_id = ''

	for i in datas:
		item = i
		tree[item['id']] = item

	root = None
	for i in datas:
		obj = i
		if not obj['pid']:
			root = tree[obj['id']]
			lists.append(root)
		else:
			parent_id = obj['pid']
			if 'childlist' not in tree[parent_id]:
				tree[parent_id]['childlist'] = []
			tree[parent_id]['childlist'].append(tree[obj['id']])

	return lists


class MyTree(APIView):

	def get(self,request):

		#获取数据
		catelist = Cate.objects.filter()
		#序列化操作
		cate_ser = CateSer(catelist,many=True)
		#格式化改造
		mylist = xTree(cate_ser.data)

		return Response(mylist)




#定义验证码类
class MyCode(View):

	#定义随机颜色
	def get_random_color(self):
		R = random.randrange(255)
		G = random.randrange(255)
		B = random.randrange(255)
		return (R,G,B)
	#获取验证码视图
	def get(self,request):
		#画布
		img_size = (120,50)
		#定义画图对象
		image = Image.new('RGB',img_size,'white')
		#定义画笔对象
		draw = ImageDraw.Draw(image,'RGB')
		#定义随机字符串
		source = '0123456789'
		#容器
		code_str = ''
		#定义字体
		my_font = ImageFont.truetype(font="c:\\Windows\\Fonts\\Arial.ttf",size=15)
		for i in range(4):
			#获取随机颜色
			text_color = self.get_random_color()
			#获取随机字符串长度下标
			tmp_num = random.randrange(len(source))
			#获取字符集
			random_str = source[tmp_num]
			#添加到容器中
			code_str += random_str
			#将字符串添加到画布中去
			draw.text((10+30*i,20),random_str,text_color,font=my_font)
		#建立缓存区
		buf = io.BytesIO()

		#将验证码存储到redis中
		r.set('code',code_str)
		#存储到session中
		request.session['code'] = code_str

		#保存图片
		image.save(buf,'png')
		return HttpResponse(buf.getvalue(),'image/png')








#md5加密方法
def make_password(mypass):

	#生成md5对象
	md5 = hashlib.md5()
	#定义机密对象
	sign_str = str(mypass)
	#转码
	sign_utf8 = sign_str.encode(encoding="utf-8")
	#加密
	md5.update(sign_utf8)
	#生成密钥串
	md5_server = md5.hexdigest()

	return md5_server


#注册模块
class Register(APIView):

	def get(self,request):

		#接收参数  dict['username']
		username = request.GET.get('username','null')
		password = request.GET.get('password','null')
		code = request.GET.get('code','null')

		print(username)
		print(password)

		#获取验证码
		redis_code = r.get('code')
		redis_code = redis_code.decode('utf-8')

		#获取session中的验证码
		session_code = request.session.get('code')

		print(code)
		print(redis_code)
		print("session: %s " % str(session_code))

		#判断验证码是否正确
		if code != redis_code:
			res = {}
			res['code'] = 405
			res['message'] = '验证码输入错误'
			return Response(res)

		#排重
		user = User.objects.filter(username=username).first()

		if user:
			res = {}
			res['code'] = 405
			res['message'] = '该用户名已存在'
			return Response(res)

		#入库
		user = User(username=username,password=make_password(password))
		user.save()

		res = {}
		res['code'] = 200
		res['message'] = '恭喜，注册成功'

		return Response(res)








#方法视图
@my_decorator
def myindex(request):

    return HttpResponse('这里是首页')


#类视图
class MyView(View):

	greeting = '你好啊'

	def get(self,request):

		title = "你好啊，Django"
		num = 100
		li = [1,2,3,4,5]
		dic = {'name':'汽车','price':100}

		#渲染模板
		return render(request,'index.html',locals())

		#return HttpResponse(self.greeting)


